﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace AdaptiveAgents.Running_Tools
{
    /// <summary>
    /// This Class process all data from the experiment FROM\TO CSV file
    /// </summary>
    class ProcessorData
    {
        /// <summary>
        /// This function process output data to statistic "DataTable" unit.
        /// </summary>
        /// <param name="title">Thetitle of the game</param>
        /// <param name="dt">Output "DataTable" unit</param>
        /// <param name="games">Number of games</param>
        /// <param name="rounds">Number of rounds</param>
        /// <param name="agents">Number of agents</param>
        /// <returns>Statistic "DataTable" unit</returns>
        public static DataTable CreateAverageDataTable(String title, DataTable dt, int games,int rounds, int agents)
        {
            DataTable returnDataTable = BuildAverageDataTable(title,rounds,agents);
            DataRow row = returnDataTable.NewRow();           
            List<DataRow> rows = new List<DataRow>();
            
            DataColumn col = dt.Columns[0];

            // get all games "DataRow" units
            int i = 0;
            for (i = 0; i < games; ++i)
            {
                rows.Add(dt.Rows[i]);
            }

            // add number of games
            row["Games"] = i;


            // add competences score
            for (int j = 0; j < agents; j++)
            {
                row["Competence_" + j] = rows[0]["Competence_" + j];
            }

            
            // add epsilons score
            for (int j = 0; j < agents; j++)
            {
                row["Epsilon_" + j] = rows[0]["Epsilon_" + j];
            }

            // add the average total grade for each agent
            double sum = 0;
            for (i = 0; i < agents; ++i)
            {
                sum = 0;
                for (int j = 0; j < games; ++j)
                {
                    sum = sum + (double)rows[j]["Total_Score_Agent_" + i];
                }
                double averageRound = sum / games;
                row["Average_Total_Score_Agent_" + i] = averageRound;
            }


            // add average number of actions for each agent
            sum = 0;
            for (i = 0; i < agents; ++i)
            {
                sum = 0;
                for (int j = 0; j < games; ++j)
                {
                    sum = sum + (double)rows[j]["Number_Actions_Agent_" + i];
                }
                double averageRound = sum / games;
                row["Average_Number_Actions_Agent_" + i] = averageRound;
            }


            // add average score per rount for each agent
            sum = 0;
            for (i = 0; i < agents; ++i)
            {
                sum = 0;
                for (int j = 0; j < games; ++j)
                {
                    sum = sum + (double)rows[j]["Average_Score_Agent_" + i];
                }
                double averageRound = sum / games;
                row["Average_Score_Agent_" + i] = averageRound;
            }
           

            // add average score for all games
            sum = 0;
            for (i = 0 ; i < games ; ++i)
            {
                sum = sum + (double)rows[i]["Average_Score"];
            }
            double averageScore = sum / games;
            row["Average_Score"] = averageScore;


            // add average max score for all games
            sum = 0;
            for (i = 0; i < games; ++i)
            {
                sum = sum + (double)rows[i]["Max_Score"];
            }
            double averageMax = sum / games;
            row["Average_Max_Score"] = averageMax;


            // add average min score for all games
            sum = 0;
            for (i = 0; i < games; ++i)
            {
                sum = sum + (double)rows[i]["Min_Score"];
            }
            double averageMin = sum / games;
            row["Average_Min_Score"] = averageMin;


            // add average sum score for all games
            sum = 0;
            for (i = 0; i < games; ++i)
            {
                sum = sum + (double)rows[i]["Sum_Score"];
            }
            double averageSumScore = sum / games;
            row["Average_Sum_Score"] = averageSumScore;


            // add average utility per round for all games
            string tempString;
            for (i = 0; i < rounds; ++i)
            {
                sum = 0;
                for (int j = 0; j < games; ++j)
                {
                    tempString = (string)rows[j]["Round_Utility_" + i];
                    sum = sum + Convert.ToDouble(tempString);
                }
                double averageRound = sum / games;
                row["Average_Round_Utility_" + i] = averageRound;
            }

            returnDataTable.Rows.Add(row);
            return returnDataTable;
        }

        
        /// <summary>
        /// This function build the "DataTable" unit for statistics CSV file.
        /// </summary>
        /// <param name="title">The game title</param>
        /// <param name="rounds">Number of rounds</param>
        /// <param name="agents">Number of agents</param>
        /// <returns>New "DataTable" unit for statistics CSV file</returns>
        private static DataTable BuildAverageDataTable(String title, int rounds, int agents)
        {
            // add title
            DataTable dt = new DataTable(title);

            // create "Games" title
            DataColumn cln = new DataColumn("Games", typeof(double));
            dt.Columns.Add(cln);

            // create "Cometence" titles
            for (int i = 0; i < agents; i++)
            {
                cln = new DataColumn("Competence_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // create "Epsilons" titles
            for (int i = 0; i < agents; i++)
            {
                cln = new DataColumn("Epsilon_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // create "Average total score" titles for each agent
            for (int i = 0; i < agents; i++)
            {
                cln = new DataColumn("Average_Total_Score_Agent_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // create "Average number actions" titles for each agent
            for (int i = 0; i < agents; i++)
            {
                cln = new DataColumn("Average_Number_Actions_Agent_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // create "Average score" titles for each agent
            for (int i = 0; i < agents; i++)
            {
                cln = new DataColumn("Average_Score_Agent_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // create "Average score" title
            cln = new DataColumn("Average_Score", typeof(double));
            dt.Columns.Add(cln);

            // create "Average Max score" title
            cln = new DataColumn("Average_Max_Score", typeof(double));
            dt.Columns.Add(cln);

            // create "Average Min score" title
            cln = new DataColumn("Average_Min_Score", typeof(double));
            dt.Columns.Add(cln);

            // create "Average Sum score" title
            cln = new DataColumn("Average_Sum_Score", typeof(double));
            dt.Columns.Add(cln);

            //add rows for each round
            for (int i = 0; i < rounds; ++i)
            {
                cln = new DataColumn(i.ToString(), typeof(double));
                dt.Columns.Add("Average_Round_Utility_" + cln);
            }
            return dt;
        }


        /// <summary>
        /// This function build the full "DataTable" unit
        /// </summary>
        /// <param name="title">Game title</param>
        /// <param name="numberOfAgents">Number of agents</param>
        /// <param name="rounds">Number of rounds</param>
        /// <returns>New "DataTable" unit</returns>
        public static DataTable CreateFullDataTable(String title, int numberOfAgents, int rounds)
        {
            // add title
            DataTable dt = new DataTable(title);

            // add "Game Number" title
            DataColumn cln = new DataColumn("Game_Number", typeof(double));
            dt.Columns.Add(cln);

            // add "Competence" titles
            for (int i = 0; i < numberOfAgents; i++)
            {
                cln = new DataColumn("Competence_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // add "Epsilons" titles
            for (int i = 0; i < numberOfAgents; i++)
            {
                cln = new DataColumn("Epsilon_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // add "Total score" title for each agents
            for (int i = 0; i < numberOfAgents; i++)
            {
                cln = new DataColumn("Total_Score_Agent_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // add "Number actions" titles for each agent
            for (int i = 0; i < numberOfAgents; i++)
            {
                cln = new DataColumn("Number_Actions_Agent_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // add "Average score" titles for each agent
            for (int i = 0; i < numberOfAgents; i++)
            {
                cln = new DataColumn("Average_Score_Agent_" + i, typeof(double));
                dt.Columns.Add(cln);
            }

            // add "Average" title
            cln = new DataColumn("Average_Score", typeof(double));
            dt.Columns.Add(cln);

            // add "Max score" title
            cln = new DataColumn("Max_Score", typeof(double));
            dt.Columns.Add(cln);

            // add "Min score" title
            cln = new DataColumn("Min_Score", typeof(double));
            dt.Columns.Add(cln);

            // add "Sum score" title
            cln = new DataColumn("Sum_Score", typeof(double));
            dt.Columns.Add(cln);

            //add rows for each round
            for (int i = 0; i < rounds; ++i)
            {
                cln = new DataColumn(i.ToString(), typeof(double));
                dt.Columns.Add("Round_Utility_" + cln);
            }
            return dt;
        }
    



    }
}
